package com.han.fu.api.business.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.han.fu.api.business.entity.User;
import com.han.fu.api.business.enums.RoleEnum;
import com.han.fu.api.business.enums.SourceEnum;
import com.han.fu.api.business.mapper.UserMapper;
import com.han.fu.api.business.model.ao.*;
import com.han.fu.api.business.model.vo.UserInfoVo;
import com.han.fu.api.business.model.vo.UserStatsVo;
import com.han.fu.api.business.model.vo.UserVo;
import com.han.fu.api.business.service.IUserService;
import com.han.fu.api.common.exception.BusinessException;
import com.han.fu.api.common.model.UserDetail;
import com.han.fu.api.common.utils.CurrentUserUtil;
import com.han.fu.common.constants.DeleteConstants;
import com.han.fu.common.constants.StringConstants;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.List;

/**
 * 用户接口实现类
 *
 * @author Star.zhu
 * @since 2020-03-26
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    protected CurrentUserUtil currentUserUtil;

    /**
     * 用户分页查询
     *
     * @param ao 查询条件
     * @return Page<UserVo> 分页数据
     */
    @Override
    public Page<UserVo> queryUserPage(UserPageAo ao) {
        return baseMapper.queryUserPage(ao);
    }

    /**
     * 用户明细查询
     *
     * @param id 明细ID
     * @return
     */
    @Override
    public UserInfoVo queryUserDetail(String id) {
        UserInfoVo userInfoVo = new UserInfoVo();
        User user = super.getById(id);
        if (null != user) {
            BeanUtils.copyProperties(user, userInfoVo);
        }
        return userInfoVo;
    }

    /**
     * 用户新增数据
     *
     * @param ao 数据
     */
    @Override
    public void addUser(UserAddAo ao) {
        boolean isExist = queryUserByAccountExist(ao.getAccount());
        if (isExist) {
            throw new BusinessException("账号已存在");
        }
        User entity = new User();
        BeanUtils.copyProperties(ao, entity);
        entity.setSource(SourceEnum.BACKGROUND.getCode());
        entity.setRole(RoleEnum.ADMIN.getCode());
        super.save(entity);
    }

    /**
     * 用户修改数据
     *
     * @param ao 数据
     */
    @Override
    public void updateUser(UserUpdateAo ao) {
        User entity = new User();
        BeanUtils.copyProperties(ao, entity);
        super.updateById(entity);
    }

    /**
     * 用户删除数据
     *
     * @param ao 数据
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteUser(UserDeleteAo ao) {
        for (String id : ao.getIds()) {
            super.removeById(id);
        }
    }

    /**
     * 用户统计查询
     *
     * @param ao 查询条件
     * @return List<UserStatsVo> 统计数据
     */
    @Override
    public List<UserStatsVo> queryUserStats(UserStatsAo ao) {
        return baseMapper.queryUserStats(ao);
    }

    /**
     * 根据UnionId查询用户信息
     *
     * @param unionId UnionId
     * @return User
     */
    @Override
    public User queryUserByUnionId(String unionId) {
        return baseMapper.queryUserByUnionId(unionId);
    }

    /**
     * 根据账号查询用户信息
     *
     * @param account 账号
     * @return User
     */
    @Override
    public User queryUserByAccount(String account) {
        return baseMapper.queryUserByAccount(account);
    }

    /**
     * 用户新增
     *
     * @param ao 数据
     */
    @Override
    public void registerUser(RegisterAo ao) {
        boolean isExist = queryUserByAccountExist(ao.getAccount());
        if (isExist) {
            throw new BusinessException("账号已存在");
        }
        User entity = new User();
        BeanUtils.copyProperties(ao, entity);
        entity.setSource(SourceEnum.WE_CHAT.getCode());
        entity.setRole(RoleEnum.TOURIST.getCode());
        super.save(entity);
    }

    /**
     * 用户修改密码
     *
     * @param ao 数据
     */
    @Override
    public void changePasswordUser(ChangePasswordAo ao) {
        // 解码
        Base64.Decoder decoder = Base64.getDecoder();
        try {
            ao.setConfirmPassword(new String(decoder.decode(ao.getConfirmPassword()), "UTF-8"));
            ao.setNewPassword(new String(decoder.decode(ao.getNewPassword()), "UTF-8"));
            ao.setPassword(new String(decoder.decode(ao.getPassword()), "UTF-8"));
            UserDetail user = currentUserUtil.getUser();
            // 修改密码
            if (user.getId().equals(ao.getId())) {
                if (ao.getNewPassword().equals(ao.getPassword())) {
                    throw new BusinessException("新密码与旧密码不能一致");
                }
                if (!ao.getNewPassword().equals(ao.getConfirmPassword())) {
                    throw new BusinessException("新密码与确认密码不一致");
                }
                if (StringConstants.WEAK.equals(checkPassword(ao.getNewPassword()))) {
                    throw new BusinessException("新密码强度太低");
                }
                User entity = super.getById(ao.getId());
                if (!ao.getPassword().equals(entity.getPassword())) {
                    throw new BusinessException("旧密码不正确");
                }
                entity.setPassword(ao.getNewPassword());
                entity.setExpire(null);
                super.updateById(entity);
            }
        } catch (UnsupportedEncodingException e) {
            log.error("密码解码失败：", e);
        }
    }

    /**
     * 用户绑定
     *
     * @param ao 数据
     */
    @Override
    public void bindingUser(BindingAo ao) {
        UserDetail detail = currentUserUtil.getUser();
        User user = baseMapper.selectById(detail.getId());
        User union = baseMapper.queryUserByUnionId(ao.getUnionId());
        if (!user.getId().equals(union.getId())) {
            if (StringUtils.isBlank(user.getUnionId())) {
                // 绑定用户
                user.setUnionId(union.getUnionId());
                baseMapper.updateById(user);
                // 注销用户
                union.setIsDeleted(DeleteConstants.DELETE);
                baseMapper.deleteById(union.getId());
            } else {
                throw new BusinessException("已被绑定其它用户");
            }
        }
    }

    /**
     * 根据账号查询用户存不存在
     *
     * @param account 账号
     * @return User
     */
    private boolean queryUserByAccountExist(String account) {
        return SqlHelper.retBool(baseMapper.queryUserByAccountCount(account));
    }

    /**
     * 密码强度
     * Z = 字母 S = 数字 T = 特殊字符
     *
     * @param password 密码
     * @return 密码强度
     */
    public String checkPassword(String password) {
        String regexZ = "\\d*";
        String regexS = "[a-zA-Z]+";
        String regexT = "\\W+$";
        String regexZT = "\\D*";
        String regexST = "[\\d\\W]*";
        String regexZS = "\\w*";

        if (password.length() <= 6) {
            return StringConstants.WEAK;
        }
        if (password.matches(regexZ)) {
            return StringConstants.WEAK;
        }
        if (password.matches(regexS)) {
            return StringConstants.WEAK;
        }
        if (password.matches(regexT)) {
            return StringConstants.WEAK;
        }
        if (password.matches(regexZT)) {
            return StringConstants.MIDDLE;
        }
        if (password.matches(regexST)) {
            return StringConstants.MIDDLE;
        }
        if (password.matches(regexZS)) {
            return StringConstants.MIDDLE;
        }
        return StringConstants.STRONG;

    }
}